package com.hengpeng.itfin.domain.partner.chinapnr.util;

public class ShaHash
{
  private int hashSize;
  private byte[] hashBytes;
  private static final boolean USE_MODIFIED_SHA = true;
  private static final int SHA_BLOCKSIZE = 64;
  private static final int SHA_DIGESTSIZE = 20;
  private int[] digest;
  private long bitCount;
  private byte[] dataB;
  private int[] dataI;
  private static final int K1 = 1518500249;
  private static final int K2 = 1859775393;
  private static final int K3 = -1894007588;
  private static final int K4 = -899497514;
  private static final int h0init = 1732584193;
  private static final int h1init = -271733879;
  private static final int h2init = -1732584194;
  private static final int h3init = 271733878;
  private static final int h4init = -1009589776;
  private int h0;
  private int h1;
  private int h2;
  private int h3;
  private int h4;
  private int A;
  private int B;
  private int C;
  private int D;
  private int E;
  private int[] W;

  public ShaHash()
  {
    this.digest = new int[5];
    this.dataB = new byte[64];
    this.dataI = new int[16];
    this.W = new int[80];
    this.hashSize = 20;
    this.hashBytes = new byte[20];
  }

  public void add(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  {
    reset();
    shaUpdate(paramArrayOfByte, paramInt1, paramInt2);
  }

  public static void copyBlock(byte[] paramArrayOfByte1, int paramInt1, byte[] paramArrayOfByte2, int paramInt2, int paramInt3)
  {
    for (int i = 0; i < paramInt3; i++)
      paramArrayOfByte2[(paramInt2 + i)] = paramArrayOfByte1[(paramInt1 + i)];
  }

  private static int f1(int paramInt1, int paramInt2, int paramInt3)
  {
    return paramInt1 & paramInt2 | (paramInt1 ^ 0xFFFFFFFF) & paramInt3;
  }

  private static int f2(int paramInt1, int paramInt2, int paramInt3)
  {
    return paramInt1 ^ paramInt2 ^ paramInt3;
  }

  private static int f3(int paramInt1, int paramInt2, int paramInt3)
  {
    return paramInt1 & paramInt2 | paramInt1 & paramInt3 | paramInt2 & paramInt3;
  }

  private static int f4(int paramInt1, int paramInt2, int paramInt3)
  {
    return paramInt1 ^ paramInt2 ^ paramInt3;
  }

  private static void fillBlock(byte[] paramArrayOfByte, byte paramByte)
  {
    fillBlock(paramArrayOfByte, 0, paramByte, paramArrayOfByte.length);
  }

  private static void fillBlock(byte[] paramArrayOfByte, int paramInt1, byte paramByte, int paramInt2)
  {
    for (int i = paramInt1; i < paramInt1 + paramInt2; i++)
      paramArrayOfByte[i] = paramByte;
  }

  public byte[] get()
  {
    prepare();
    byte[] arrayOfByte1 = new byte[this.hashSize + 108];
    byte[] arrayOfByte2 = { 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    System.arraycopy(arrayOfByte2, 0, arrayOfByte1, 0, 108);
    System.arraycopy(this.hashBytes, 0, arrayOfByte1, 108, this.hashSize);
    return arrayOfByte1;
  }

  public void prepare()
  {
    shaFinal();
    spreadIntsToBytes(this.digest, 0, this.hashBytes, 0, 5);
  }

  public void reset()
  {
    shaInit();
  }

  private static int rotateL(int paramInt1, int paramInt2)
  {
    return paramInt1 << paramInt2 | paramInt1 >>> 32 - paramInt2;
  }

  public void shaFinal()
  {
    int i = (int)(this.bitCount >>> 3) & 0x3F;
    this.dataB[(i++)] = -128;
    if (i > 56)
    {
      fillBlock(this.dataB, i, (byte)0, 64 - i);
      squashBytesToInts(this.dataB, 0, this.dataI, 0, 16);
      shaTransform();
      fillBlock(this.dataB, 0, (byte)0, 56);
    }
    else {
      fillBlock(this.dataB, i, (byte)0, 56 - i);
    }
    squashBytesToInts(this.dataB, 0, this.dataI, 0, 16);
    this.dataI[14] = ((int)(this.bitCount >>> 32));
    this.dataI[15] = ((int)(this.bitCount & 0xFFFFFFFF));
    shaTransform();
  }

  private void shaInit()
  {
    this.digest[0] = 1732584193;
    this.digest[1] = -271733879;
    this.digest[2] = -1732584194;
    this.digest[3] = 271733878;
    this.digest[4] = -1009589776;
    this.bitCount = 0L;
  }

  public void shaTransform()
  {
	int i=0;
    for (i = 0; i < 16; i++) {
      this.W[i] = this.dataI[i];
    }
    for (; i < 80; i++)
    {
      this.W[i] = (this.W[(i - 3)] ^ this.W[(i - 8)] ^ this.W[(i - 14)] ^ this.W[(i - 16)]);
      this.W[i] = rotateL(this.W[i], 1);
    }

    this.A = this.digest[0];
    this.B = this.digest[1];
    this.C = this.digest[2];
    this.D = this.digest[3];
    this.E = this.digest[4];
    for (i = 0; i < 20; i++) {
      subRound1(i);
    }
    for (; i < 40; i++) {
      subRound2(i);
    }
    for (; i < 60; i++) {
      subRound3(i);
    }
    for (; i < 80; i++) {
      subRound4(i);
    }
    this.digest[0] += this.A;
    this.digest[1] += this.B;
    this.digest[2] += this.C;
    this.digest[3] += this.D;
    this.digest[4] += this.E;
  }

  public void shaUpdate(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  {
    this.bitCount += (paramInt2 << 3);
    for (; paramInt2 >= 64; paramInt2 -= 64)
    {
      copyBlock(paramArrayOfByte, paramInt1, this.dataB, 0, 64);
      squashBytesToInts(this.dataB, 0, this.dataI, 0, 16);
      shaTransform();
      paramInt1 += 64;
    }

    copyBlock(paramArrayOfByte, paramInt1, this.dataB, 0, paramInt2);
  }

  private static void spreadIntsToBytes(int[] paramArrayOfInt, int paramInt1, byte[] paramArrayOfByte, int paramInt2, int paramInt3)
  {
    for (int i = 0; i < paramInt3; i++)
    {
      paramArrayOfByte[(paramInt2 + i * 4)] = ((byte)(paramArrayOfInt[(paramInt1 + i)] >>> 24));
      paramArrayOfByte[(paramInt2 + i * 4 + 1)] = ((byte)(paramArrayOfInt[(paramInt1 + i)] >>> 16));
      paramArrayOfByte[(paramInt2 + i * 4 + 2)] = ((byte)(paramArrayOfInt[(paramInt1 + i)] >>> 8));
      paramArrayOfByte[(paramInt2 + i * 4 + 3)] = ((byte)paramArrayOfInt[(paramInt1 + i)]);
    }
  }

  private static void squashBytesToInts(byte[] paramArrayOfByte, int paramInt1, int[] paramArrayOfInt, int paramInt2, int paramInt3)
  {
    for (int i = 0; i < paramInt3; i++)
      paramArrayOfInt[(paramInt2 + i)] = ((paramArrayOfByte[(paramInt1 + i * 4)] & 0xFF) << 24 | (paramArrayOfByte[(paramInt1 + i * 4 + 1)] & 0xFF) << 16 | (paramArrayOfByte[(paramInt1 + i * 4 + 2)] & 0xFF) << 8 | paramArrayOfByte[(paramInt1 + i * 4 + 3)] & 0xFF);
  }

  private void subRound1(int paramInt)
  {
    int i = rotateL(this.A, 5) + f1(this.B, this.C, this.D) + this.E + this.W[paramInt] + 1518500249;
    this.E = this.D;
    this.D = this.C;
    this.C = rotateL(this.B, 30);
    this.B = this.A;
    this.A = i;
  }

  private void subRound2(int paramInt)
  {
    int i = rotateL(this.A, 5) + f2(this.B, this.C, this.D) + this.E + this.W[paramInt] + 1859775393;
    this.E = this.D;
    this.D = this.C;
    this.C = rotateL(this.B, 30);
    this.B = this.A;
    this.A = i;
  }

  private void subRound3(int paramInt)
  {
    int i = rotateL(this.A, 5) + f3(this.B, this.C, this.D) + this.E + this.W[paramInt] + -1894007588;
    this.E = this.D;
    this.D = this.C;
    this.C = rotateL(this.B, 30);
    this.B = this.A;
    this.A = i;
  }

  private void subRound4(int paramInt)
  {
    int i = rotateL(this.A, 5) + f4(this.B, this.C, this.D) + this.E + this.W[paramInt] + -899497514;
    this.E = this.D;
    this.D = this.C;
    this.C = rotateL(this.B, 30);
    this.B = this.A;
    this.A = i;
  }

  private static String toStringBlock(byte[] paramArrayOfByte)
  {
    return toStringBlock(paramArrayOfByte, 0, paramArrayOfByte.length);
  }

  private static String toStringBlock(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  {
    String str = "0123456789abcdef";
    StringBuffer localStringBuffer = new StringBuffer();
    for (int i = paramInt1; i < paramInt1 + paramInt2; i++)
    {
      localStringBuffer.append(str.charAt(paramArrayOfByte[i] >>> 4 & 0xF));
      localStringBuffer.append(str.charAt(paramArrayOfByte[i] & 0xF));
    }

    return String.valueOf(String.valueOf(localStringBuffer));
  }
}
